<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Pluralizer;

class Controller extends BaseController
{
  use AuthorizesRequests;
  use DispatchesJobs;
  use ValidatesRequests;

  protected $coreApiPublicEndpoint;
  protected $coreApiEndpoint;
  protected $fullLocale;

  protected $model;
  protected $endpoint;

  public function __construct(Request $request, string $model = null, string $endpoint = null)
  {
    $this->coreApiEndpoint = env('CORE_API_ENDPOINT');
    $this->coreApiPublicEndpoint = env('CORE_API_PUBLIC_ENDPOINT');
    if ((Session::has('locale'))) {
      $this->fullLocale = Session::get('locale');
    } else {
      $this->fullLocale = env('APP_LOCALE');
    }
    if ('it' == $this->fullLocale) {
      $this->fullLocale .= '_IT';
    }
    if ('en' == $this->fullLocale) {
      $this->fullLocale .= '_US';
    }
    if (isset($model)) {
      $this->model = $model;
      Log::info("Controller for {$this->model}");
    }
    if (isset($endpoint)) {
      $this->endpoint = $endpoint;
    }
  }

  public function index(Request $request)
  {
    Log::info(__METHOD__);

    $coreApiEndpointUrl = $coreBgEndpointUrl = $fullEndpoint = '';
    $params = $endpointResponse = $resultsData = $results = $pagination = $links = $response = null;
    $session = $request->session();
    $bearer = $session->get('coreapi_token');
    $filterValue = $request->input('filter_email');

    $coreApiEndpointUrl = $this->coreApiEndpoint . "/{$this->endpoint}";
    if (!$request->exists('limit')) {
      $request->request->add(['limit' => env('DEFAULT_INDEX_LIMIT')]);
    }
    $params = $request->query();
    $coreApiEndpointUrl = addParamsToUrl($coreApiEndpointUrl, $params);
    $coreBgEndpointUrl = addParamsToUrl(env('CORE_BG_ENDPOINT') . '/' . $this->endpoint, $params);
    $fullEndpoint = env('CORE_BG_ENDPOINT') . '/' . $this->endpoint;
    $resultsData = getFromCoreApi($bearer, $coreApiEndpointUrl);
    $results = $resultsData['data'];
    $links = $resultsData['links'];
    $pagination = $resultsData['meta'];
    $links = str_replace(
      env('CORE_API_ENDPOINT'),
      env('CORE_BG_ENDPOINT'),
      $links
    );
    if ($request->ajax()) {
      $response = view($this->endpoint . '.load_data', compact('results', 'pagination', 'links', 'fullEndpoint', 'filterValue'));
    } else {
      $response = view($this->endpoint . '.index', compact('results', 'pagination', 'links', 'fullEndpoint', 'filterValue'));
    }

    return $response;
  }

  public function destroy(Request $request, $id)
  {
    Log::info(__METHOD__);

    $coreApiEndpointUrl = '';
    $response = null;
    $session = $request->session();
    $bearer = $session->get('coreapi_token');

    $coreApiEndpointUrl = $this->coreApiEndpoint . "/{$this->endpoint}/$id";
    $response = delFromCoreApi($bearer, $coreApiEndpointUrl);

    return $response;
  }

  public function show(Request $request, $id)
  {
    Log::info(__METHOD__);

    $coreApiEndpointUrl = '';
    $resourcesData = $resources = $response = null;
    $session = $request->session();
    $bearer = $session->get('coreapi_token');
    $backurl = url()->previous();
    $backurl = removeSearchFromUrl($backurl);
    $currenturl = url()->current();

    $params = $request->query();
    $coreApiEndpointUrl = $this->coreApiEndpoint . "/{$this->endpoint}/$id";
    if (isset($params['include'])) {
      $coreApiEndpointUrl = addIncludeToUrl($coreApiEndpointUrl, $params['include']);
    }
    $resourcesData = getFromCoreApi($bearer, $coreApiEndpointUrl);
    $resource = $resourcesData['resource'];
    $response = view($this->endpoint . '.show', compact('resource', 'backurl', 'currenturl'));

    return $response;
  }

  public function create()
  {
    Log::info(__METHOD__);

    $backurl = url()->previous();
    $backurl = removeSearchFromUrl($backurl);
    $currenturl = url()->current();
    $resource = null;

    $response = view($this->endpoint . '.create', compact('resource', 'backurl', 'currenturl'));

    return $response;
  }

  public function store(Request $request)
  {
    Log::info(__METHOD__);

    $coreApiEndpointUrl = '';
    $resourcesData = $resource = $response = null;
    $session = $request->session();
    $bearer = $session->get('coreapi_token');
    $backurl = $this->endpoint;
    $backurl = removeSearchFromUrl($backurl);
    $currenturl = url()->current();

    $data = $request->all();
    $coreApiEndpointUrl = $this->coreApiEndpoint . "/{$this->endpoint}";
    $resourcesData = postToCoreApi($bearer, $coreApiEndpointUrl, $data);
    if (isset($resourcesData['resource'])) {
      $resource = $resourcesData['resource'];
      $response = view($this->endpoint . '.show', compact('resource', 'backurl', 'currenturl'));
    }
    if (isset($resourcesData['error'])) {
      $resource = $data;

      $response = view($this->endpoint . '.create', compact('resource', 'backurl', 'currenturl'))->withErrors($resourcesData['error']);
    }

    return $response;
  }

  public function edit(Request $request, $id)
  {
    Log::info(__METHOD__);

    $coreApiEndpointUrl = '';
    $resourcesData = $resources = $response = null;
    $session = $request->session();
    $bearer = $session->get('coreapi_token');
    $backurl = url()->previous();
    $backurl = removeSearchFromUrl($backurl);
    $currenturl = url()->current();

    $params = $request->query();
    $coreApiEndpointUrl = $this->coreApiEndpoint . "/{$this->endpoint}/$id";
    if (isset($params['include'])) {
      $coreApiEndpointUrl = addIncludeToUrl($coreApiEndpointUrl, $params['include']);
    }
    $resourcesData = getFromCoreApi($bearer, $coreApiEndpointUrl);
    $resource = $resourcesData['resource'];
    $response = view($this->endpoint . '.edit', compact('resource', 'backurl', 'currenturl'));

    return $response;
  }

  public function update(Request $request, $id)
  {
    Log::info(__METHOD__);

    $coreApiEndpointUrl = '';
    $resourcesData = $resource = $response = null;
    $session = $request->session();
    $bearer = $session->get('coreapi_token');
    $backurl = '/' . $this->endpoint;
    $backurl = removeSearchFromUrl($backurl);
    $currenturl = url()->current();

    $data = $request->all();
    $coreApiEndpointUrl = $this->coreApiEndpoint . "/{$this->endpoint}/$id";
    $resourcesData = putToCoreApi($bearer, $coreApiEndpointUrl, $data);
    if (isset($resourcesData['resource'])) {
      $resource = $resourcesData['resource'];
      $response = view($this->endpoint . '.show', compact('resource', 'backurl', 'currenturl'));
    }
    if (isset($resourcesData['error'])) {
      $resource = $data;
      $response = view($this->endpoint . '.show', compact('resource', 'backurl', 'currenturl'))->withErrors($resourcesData['error']);
    }

    return $response;
  }
}
